package com.jayson.server.catalina;

import com.jayson.server.utils.MyClassLoader;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 上下文类
 * 保存上下文名称和Servlet容器Wrapper
 */
public class Context {

    private String context;

    private List<Wrapper> wrappers = new ArrayList<>();

    public String getContext() {
        return context;
    }

    public void setContext(String context) {
        this.context = context;
    }

    public List<Wrapper> getWrappers() {
        return wrappers;
    }

    public void setWrappers(List<Wrapper> wrappers) {
        this.wrappers = wrappers;
    }

    /**
     * 初始化应用上下文
     * @param file
     */
    public void init(File file){
        if(file.isFile()){
            throw new RuntimeException("======>>>>>>文件路径错误");
        }

        this.context = file.getName();
        try {
            initWrapper(file);

        } catch (DocumentException | ClassNotFoundException | NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

    }

    /**
     * 解析文件路径下的 web.xml 同时生成对应的servlet对象，并封装到应用上下文中
     *
     * @param file
     */
    private void initWrapper(File file) throws DocumentException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, FileNotFoundException, MalformedURLException {
        InputStream resourceAsStream = Context.class.getClassLoader().getResourceAsStream("web.xml");

        File webFile = new File(file.getAbsolutePath() + "/web.xml");
        if(!webFile.exists()){
            throw new RuntimeException("======>>>>>>文件路径错误");
        }
        // 解析web.xml
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(webFile);
        Element rootElement = document.getRootElement();
        List<Element> servletElements = rootElement.selectNodes("servlet");
        for (Element servletElement : servletElements) {

            String servletName = servletElement.selectSingleNode("servlet-name").getStringValue();
            String servletClass = servletElement.selectSingleNode("servlet-class").getStringValue();

            Element servletMapping = (Element) rootElement.selectSingleNode("/web-app/servlet-mapping[servlet-name='" + servletName + "']");
            String urlPattern = servletMapping.selectSingleNode("url-pattern").getStringValue();

            // 生成servlet对象
            Servlet servlet = null;
            MyClassLoader myClassLoader=new MyClassLoader(file.getAbsolutePath());
            Class c=myClassLoader.loadClass(servletClass);
            if(c!=null){
                Object obj=c.getDeclaredConstructor().newInstance();
                servlet = (Servlet) obj;
            }

            // 封装wrapper，并设置到应用上下文中
            Wrapper wrapper = new Wrapper(urlPattern, servlet);
            this.wrappers.add(wrapper);
        }

    }


}
